home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / graphic / dbwrendr.zip / SOURCE / VAL.C < prev   
C/C++ Source or Header  |  1989-04-17  |  16KB  |  394 lines

  1. /************************************************************************
  2.  *                                                                      *
  3.  *                  Copyright (c) 1987, David B. Wecker                 *
  4.  *                          All Rights Reserved                         *
  5.  *                                                                      *
  6.  * This file is part of DBW_Render                                      *
  7.  *                                                                      *
  8.  * DBW_Render is distributed in the hope that it will be useful, but    *
  9.  * WITHOUT ANY WARRANTY. No author or distributor accepts               *
  10.  * responsibility to anyone for the consequences of using it or for     *
  11.  * whether it serves any particular purpose or works at all, unless     *
  12.  * he says so in writing. Refer to the DBW_Render General Public        *
  13.  * License for full details.                                            *
  14.  *                                                                      *
  15.  * Everyone is granted permission to copy, modify and redistribute      *
  16.  * DBW_Render, but only under the conditions described in the           *
  17.  * DBW_Render General Public License. A copy of this license is         *
  18.  * supposed to have been given to you along with DBW_Render so you      *
  19.  * can know your rights and responsibilities. It should be in a file    *
  20.  * named COPYING. Among other things, the copyright notice and this     *
  21.  * notice must be preserved on all copies.                              *
  22.  ************************************************************************
  23.  *                                                                      *
  24.  * Authors:                                                             *
  25.  *      DBW - David B. Wecker                                           *
  26.  *                                                                      *
  27.  * Versions:                                                            *
  28.  *      V1.0 870125 DBW - First released version                        *
  29.  *                                                                      *
  30.  ************************************************************************/
  31.  
  32. #define MODULE_VAL
  33. #include "ray.h"
  34.  
  35. void getval(val,np,p,d,atten,ambientlight)
  36. vector      val,
  37.   p,
  38.   d;
  39. node        *np;
  40. float       atten;
  41. int         ambientlight;
  42. {
  43.      vector      pseudodirection,
  44.      pseudointensity,
  45.      tp,
  46.      lightdir,
  47.      lightint,
  48.      penumbra,
  49.      transparency,
  50.      best_p,
  51.      nval,
  52.      n,
  53.      r,
  54.      temp,
  55.      specintensity,
  56.      diffuse,
  57.      v1;
  58.      float       best_t,
  59.        ndotdir,
  60.        t,
  61.        texture,
  62.        td,
  63.        pointdist,
  64.        umbscale;
  65.      float       ndotd,
  66.        ambientscale;
  67.      int         hitnext,
  68.        lit,
  69.        i,
  70.        itd;
  71.      node        *bouncenp,
  72.      *occlude;
  73.      vector      light_atten[MAXLIT];
  74.      int         l_objcounter;
  75.      float       l_distances[MAXOBJ];
  76.      node        *l_objpairs[MAXOBJ];
  77.      vector      l_points[MAXOBJ];
  78.  
  79.      if (allopaque == 0) 
  80.      { /* If not opaque,then save the ray intersection list */
  81.           l_objcounter = g_objcounter;
  82.           for (i = 0; i < l_objcounter; i++) 
  83.           {
  84.                l_distances[i] = g_distances[i];
  85.                l_objpairs[i] = g_objpairs[i];
  86.                veccopy(g_points[i],l_points[i]);
  87.           }
  88.      }
  89.  
  90.      veczero(val);  /* start with output value of zero */
  91.  
  92.      findnormal(np,p,n);
  93.      ndotd = DOT(n,d);
  94.      if (ndotd > 0.0) 
  95.      {          /* We're looking at surface's back side */
  96.           ndotd = -ndotd;
  97.           n[0] = -n[0];  /* Flip the normal */
  98.           n[1] = -n[1];
  99.           n[2] = -n[2];
  100.      }
  101.  
  102.      /* Initialize the light attenuation values with 'not-yet-computed' flag */
  103.  
  104.      for (lit = 0; lit < numlits; lit++)
  105.           light_atten[lit][0] = -99.9;
  106.  
  107.      /* Apply procedural texture */
  108.      gettex(diffuse,np,p,n);
  109.  
  110.      /*---------------------------------------------------------------------*/
  111.      /* Compute diffuse reflection intensity */
  112.  
  113.      if (diffuse[0] > 0.01 || diffuse[1] > 0.01 || diffuse[2] > 0.01) 
  114.      {
  115.  
  116.           /* First,compute light shining directly on this point */
  117.           for (lit = 0; lit < numlits; lit++) 
  118.           { 
  119.                veccopy(light[lit].direction,lightdir);
  120.                veccopy(light[lit].intensity,lightint);
  121.  
  122.                pointdist = 0.0;
  123.  
  124.                if (light[lit].kind != 0) 
  125.                { /* If point source,compute local direction */
  126.                     vecsub(lightdir,p,lightdir);
  127.                     pointdist = NORM(lightdir);  /* distance to point light source */
  128.                     if (pointdist == 0.0)
  129.                          pointdist = 0.01;
  130.                     umbscale  = light[lit].distscale;
  131.                     umbscale /= pointdist * pointdist;
  132.                     vecscale(umbscale,lightint,lightint);
  133.                     CV(rnd(),rnd(),rnd(),penumbra);
  134.                     if (rnd() < 0.5)
  135.                          penumbra[0] = -penumbra[0];
  136.                     if (rnd() < 0.5)
  137.                          penumbra[1] = -penumbra[1];
  138.                     if (rnd() < 0.5)
  139.                          penumbra[2] = -penumbra[2];
  140.                     normalize(penumbra);  /* penumbra is now random unit vector */
  141.  
  142.                     umbscale  = rnd();
  143.                     umbscale -= 0.05;
  144.                     umbscale *= light[lit].radius;
  145.                     vecscale(umbscale,penumbra,penumbra);
  146.                     vecsum(penumbra,lightdir,lightdir);
  147.                     normalize(lightdir);
  148.                }
  149.  
  150.                /* Now that we know where the light is shining from,compute diffuse
  151.                (lamertian) reflection */
  152.  
  153.                ndotdir = DOT(n,lightdir);
  154.                if (ndotdir > 0.0) 
  155.                {
  156.                     vecmul(lightint,diffuse,nval);
  157.                     vecscale(ndotdir,nval,nval);
  158.                }
  159.                else
  160.                {
  161.                     veczero(nval);  /* self shadowing -- backside of spheres,etc. */
  162.                }
  163.  
  164.                /* If the computed diffuse surface brightness is above a certain
  165.                threshold level,then compute the shadow attenuation */
  166.  
  167.                if (nval[0] > 0.01 || nval[1] > 0.01 || nval[2] > 0.01) 
  168.                {
  169.                     getatten(light_atten[lit],p,lightdir,lit,pointdist);
  170.                     vecmul(nval,light_atten[lit],nval); /* attenuate */
  171.                }
  172.                vecsum(nval,val,val);  /* Sum up for all light sources */
  173.           } /* for */
  174.  
  175.           /*---------------------------------------------------------------------*/
  176.           /* Next,compute light shining indirectly from any surfaces on this    */
  177.           /* point.  This is done to approximate true ambient illumination.      */
  178.  
  179.           for (lit = 0; lit < ambientlight; lit++) 
  180.           {
  181.                ambientscale = 1.0 / (float) ambientlight;
  182.                /* ?? not sure how to factor in distance from diffuse reflector */
  183.  
  184.                CV(rnd(),rnd(),rnd(),lightdir);
  185.                if (rnd() < 0.5)
  186.                     lightdir[0] = -lightdir[0];
  187.                if (rnd() < 0.5)
  188.                     lightdir[1] = -lightdir[1];
  189.                if (rnd() < 0.5)
  190.                     lightdir[2] = -lightdir[2];
  191.                normalize(lightdir);  /* lightdir is now random unit vector */
  192.  
  193.                ndotdir = DOT(n,lightdir);
  194.                if (ndotdir < 0.0) 
  195.                { /* if not in upper hemisphere,invert it */
  196.                     lightdir[0] = -lightdir[0];
  197.                     lightdir[1] = -lightdir[1];
  198.                     lightdir[2] = -lightdir[2];
  199.                     ndotdir = -ndotdir;
  200.                }
  201.  
  202.                /* okay,now the direction is known.  What is visible there? */
  203.                dodirection(nval,p,lightdir,ambientscale,
  204.                  ambientlight * amblitnum / amblitdenom);
  205.  
  206.                val[0] += nv